package com.fowo.api.sys.service.impl;

import com.fowo.api.sys.service.SysDevService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StreamUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统开发服务
 */
@Service
public class SysDevServiceImpl implements SysDevService {
    @Resource
    private ResourceLoader resourceLoader;

    // 保存开发时替换过的脚本体
    private final Map<String, String> scriptCustoms = new HashMap<>();

    @Override
    public List<String> getScriptNames() {
        ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        try {
            org.springframework.core.io.Resource[] resources = resolver.getResources( ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "/scripts/*.js");
            return Arrays.stream(resources).map(org.springframework.core.io.Resource::getFilename).collect(Collectors.toList());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String readScriptInResource(String scriptResPath) {
        try (InputStream inputStream = new ClassPathResource(scriptResPath).getInputStream()) {
            return StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String getScriptByName(String name) {
        if (name.startsWith("scripts/")) {
            name = name.substring(8);
        }
        return scriptCustoms.computeIfAbsent(name, n -> {
            String scriptResPath = String.format("scripts/%s", n);
            return readScriptInResource(scriptResPath);
        });
    }

    @Override
    public void updateScriptByName(String name, String script) {
        scriptCustoms.put(name, script);
    }

    @Override
    public void removeScript(String name) {
        scriptCustoms.remove(name);
    }
}
